The simplest C IRC bot possible
- By pat
- In c programming sockets
- With No Comments
- On 10 Feb | '2011
All of my programming classes in college were in C, but unfortunately I forgot most of it. I’ve been trying to re-learn, and I started with the simplest IRC bot possible. This code simply connects to an IRC server by its IP address on port 6667, logs in, and responds to PING commands.
I start by creating a socket.
if ( (*sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
Inet_pton is used to convert a IP address string into a number. Inet_aton would also work but there is no reason to use it as pton also supports IPV6 addresses.
if (inet_pton(AF_INET, server, &servaddr.sin_addr) <= 0) {
Connect is called to well, connect to the server.
if (connect(*sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 )
Once the bot is connected to the IRC server, you simply need to provide your user and nickname. See RFC 1459 for more details.
my_send(sockfd, "NICK clark\r\n", debug);
my_send(sockfd, "USER clark 8 * : Clark Clarkerson\r\n", debug);
Join a channel:
my_send(sockfd, "JOIN #pat\r\n", debug);
Now all that is left to do read any network traffic the server sends. In particular we are looking for the PING command from the server.
n = my_read(sockfd, recvline, debug);
if (n > 0) {
recvline[n] = 0;
if (strstr(recvline, "PING") != NULL) {
out[0] = 0;
pos = strstr(recvline, " ")+1;
sprintf(out, "PONG %s\r\n", pos);
my_send(sockfd, out, debug);
}
}
Once I receive a PING command I generate a PONG command that includes the parameter sent with the PING command. For example if I received “PING irc.example.com”, I respond with “PONG irc.example.com”.
That’s it! The entire code is below. I will be adding some additional features in a later post.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#define MAXLINE 4096
int my_connect(char *server, unsigned int port, int *sockfd);
int my_send(int sockfd, char *out, int debug);
int my_read(int sockfd, char *recvline, int debug);
int main(int argc, char **argv) {
int sockfd, n, debug;
char recvline[MAXLINE+1], out[MAXLINE+1];
char *cmd, *pos;
char server[] = "64.150.185.111";
debug = 1;
if (!my_connect(server, 6667, &sockfd)) {
printf("Failed to connect to %s.\n", server);
exit(1);
}
my_send(sockfd, "NICK clark\r\n", debug);
my_send(sockfd, "USER clark 8 * : Clark Clarkerson\r\n", debug);
my_send(sockfd, "JOIN #pat\r\n", debug);
while(1) {
recvline[0] = 0;
n = my_read(sockfd, recvline, debug);
if (n > 0) {
recvline[n] = 0;
if (strstr(recvline, "PING") != NULL) {
out[0] = 0;
pos = strstr(recvline, " ")+1;
sprintf(out, "PONG %s\r\n", pos);
my_send(sockfd, out, debug);
}
}
}
exit(0);
}
int my_connect(char *server, unsigned int port, int *sockfd) {
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
if ( (*sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
return 0;
}
if (inet_pton(AF_INET, server, &servaddr.sin_addr) <= 0) {
return 0;
}
if (connect(*sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 ) {
return 0;
}
return 1;
}
int my_send(int sockfd, char *out, int debug) {
if (debug) {
printf("OUT: %s", out);
}
return send(sockfd, out, strlen(out), 0);
}
int my_read(int sockfd, char *recvline, int debug) {
int n;
n = read(sockfd, recvline, MAXLINE);
if (n > 0 && debug) {
printf("IN: %s", recvline);
}
return n;
}